#include "CWndBase.h"

CWndBase::CWndBase():
m_hWnd(NULL),
m_hWndParent(NULL),
m_dwStyle(WS_TABSTOP)
{
	memset(m_strWndClass, 0, WND_NAME_LEN*sizeof(TCHAR));
	memset(m_strWndName, 0, WND_NAME_LEN*sizeof(TCHAR));
}

CWndBase::~CWndBase()
{	
}

BOOL CWndBase::Create(HWND hWndParent, LPCTSTR &strWndClass, LPCTSTR &strWndName)
{
	DWORD dwWndStyle;
	if(hWndParent==NULL)
	{
		dwWndStyle = WS_VISIBLE|WS_POPUP;
	}
	else
	{
		dwWndStyle = WS_VISIBLE|WS_CHILD;
	}
	return CreateEx(hWndParent,strWndClass,strWndName,dwWndStyle/*WS_VISIBLE|WS_POPUP*//*WS_TABSTOP*/);
}

BOOL CWndBase::CreateEx(HWND hWndParent, LPCTSTR &strWndClass, LPCTSTR &strWndName,DWORD dwStyle)
{
	m_hWndParent = hWndParent;
	m_dwStyle = dwStyle;

	wcscpy_s(m_strWndName, WND_NAME_LEN, strWndName);
	wcscpy_s(m_strWndClass, WND_NAME_LEN, strWndClass);

	if(CreateWnd(dwStyle,0))
	{
		//SetParentWindow(hWndParent);
		return TRUE;
	}
	return FALSE;
}

BOOL CWndBase::RegisterClass()
{	
	WNDCLASS wc;
	GetDataForRegistryClass(wc);

	return ::RegisterClass(&wc);
}

LRESULT CALLBACK CWndBase::StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	CWndBase *pObject = reinterpret_cast<CWndBase*>(GetWindowLong(hWnd, GWL_USERDATA));
	if(pObject)
	{
		return pObject->WndProc(hWnd,wMsg,wParam,lParam);
	}
	else
	{
		return DefWindowProc(hWnd,wMsg,wParam,lParam);
	}
}

BOOL CWndBase::ShowWindow(BOOL bShow)
{
	if(m_hWnd == NULL)
	{
		return FALSE;
	}
	if(bShow == TRUE)
	{
		::ShowWindow(m_hWnd,SW_SHOW);
	}
	else
	{
		::ShowWindow(m_hWnd,SW_HIDE);
	}
	return TRUE;
}


BOOL CWndBase::CreateWnd(DWORD dwStyle,DWORD dwExStyle)
{	
	if(RegisterClass() == FALSE)
	{
		return FALSE;
	}

	RECT rcArea = {0};
	SystemParametersInfo(SPI_GETWORKAREA, 0, &rcArea, 0);

	m_hWnd = CreateWindowEx(dwExStyle,
		m_strWndClass,
		m_strWndName,
		dwStyle,
		rcArea.left,
		rcArea.top,
		rcArea.right - rcArea.left,
		rcArea.bottom - rcArea.top,
		m_hWndParent, 
		NULL, 
		GetModuleHandle(NULL), 
		0);

	//ASSERT(m_hWnd != FALSE);

	if (IsWindow(m_hWnd) == FALSE)
	{
		return FALSE;
	}

	// If the window is created successfully, store this object so the 
	//static wrapper can pass calls to the real WndProc.
	SetWindowLong(m_hWnd, GWL_USERDATA, reinterpret_cast<DWORD>(this));

	return TRUE;
}

HWND CWndBase::GetWindow(void) const
{
	return m_hWnd;
}

HWND CWndBase::GetParentWindow(void) const
{
	if(m_hWnd != NULL)
	{
		m_hWndParent = ::GetParent(m_hWnd);
	}
	return m_hWndParent;
}

BOOL CWndBase::SetParentWindow(HWND hWndParent)
{
	if(m_hWnd == NULL)
	{
		m_hWndParent = hWndParent;
		return TRUE;
	}

	LONG lStyle = GetWindowLong(m_hWnd,GWL_STYLE);
	lStyle &= ~WS_POPUP;  //Remove the WS_POPUP flag
	lStyle |= WS_CHILD;	  //Set the WS_CHILD flag
	SetWindowLong(m_hWnd,GWL_STYLE,lStyle);

	::SetParent(m_hWnd,hWndParent);
	m_hWndParent = GetParentWindow();

	return (m_hWndParent != NULL);

}

void CWndBase::GetDataForRegistryClass(WNDCLASS &wc)
{
	wc.style         = 0;
	wc.lpfnWndProc   = CWndBase::StaticWndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = GetModuleHandle(NULL);
	wc.hIcon         = NULL; 
	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);	
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = m_strWndClass;	
	wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
}


void CWndBase::OnLButtonDown(UINT nFlags, POINT point)
{
	return;
}

void CWndBase::OnLButtonUp(UINT nFlags, POINT point)
{
	return;
}


LRESULT CWndBase::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	switch(wMsg)
	{
	case WM_DESTROY: 
		break;
	case WM_LBUTTONDOWN:
		{
			POINT pt;
			pt.x=LOWORD(lParam);
			pt.y=HIWORD(lParam);
			OnLButtonDown(wParam,pt);
		}
		break;
	case WM_LBUTTONUP:
		{
			POINT pt;
			pt.x=LOWORD(lParam);
			pt.y=HIWORD(lParam);
			OnLButtonUp(wParam,pt);
		}
		break;
	/*case WM_CLOSE:
		OutputDebugString(_T("WM_CLOSE\n"));
		break;
	case WM_QUIT:
		OutputDebugString(_T("WM_QUIT\n"));
		break;*/
	}
	return DefWindowProc(hWnd,wMsg,wParam,lParam);
}